package org.dydl.common.config;

import org.dydl.common.security.AuthenticationProviderCustom;
import org.dydl.common.security.CAPTCHAAuthenticationFilter;
import org.dydl.common.security.impl.AuthenticationFailureHandlerImpl;
import org.dydl.common.security.impl.AuthenticationSuccessHandlerImpl;
import org.dydl.common.security.impl.LogoutSuccessHandlerImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

//@EnableGlobalMethodSecurity(securedEnabled = true)
//@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@Component
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Value("${login.url}")
	private String loginUrl;

	@Bean
	UserDetailsService customUserService() { // 2
		return new CustomUserService();
	}

	// @Autowired
	// private AuthTokenGeneratorService authTokenGeneratorService;

	// @Autowired
	// private IAuthTokenService authTokenService;

	// @Autowired
	// private ISysRightsService sysRightsService;

	@Override
	protected void configure(HttpSecurity http) throws Exception {

		// 关闭CSRF验证
		http.csrf().disable();
		// 解决错误："Refused to display 'http://......' in a frame because it set
		// 'X-Frame-Options' to 'DENY'.
		http.headers().frameOptions().disable();

		http.addFilterBefore(new CAPTCHAAuthenticationFilter(loginUrl), UsernamePasswordAuthenticationFilter.class)
				// .addFilterBefore(new TokenAuthenticationFilter("/api/**",
				// authTokenGeneratorService, authTokenService),
				// BasicAuthenticationFilter.class)
				.formLogin().loginPage(loginUrl).failureUrl("/public/logout")
				.failureHandler(authenticationFailureHandler()).successHandler(authenticationSuccessHandler())
				.permitAll().and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/public/logout"))
				.logoutSuccessHandler(logoutSuccessHandler()).and()
				// .rememberMe()
				// .key("rem-me-key")
				// .rememberMeParameter("remember_me_param")
				// .and()
				.sessionManagement().sessionAuthenticationErrorUrl("/public/logout").and().exceptionHandling()
				.authenticationEntryPoint(new CustomEntryPoint(loginUrl)).and().httpBasic();

		// ........................................................
		// List<SysRights> sysRightsList = sysRightsService.getAll();
		// List<SysRights> sysRightsList = (List<SysRights>) sysRightsService.search(new
		// Search()).getData();

		// for (SysRights sysRights : sysRightsList) {
		// // 过滤掉请求资源
		// if (null != sysRights.getResType() && !sysRights.getResType().equals("2")) {
		// String url = sysRights.getUrl();
		// // String[] roles = sysRights.getRoles();
		//
		// List<SysRole> roles = (List<SysRole>)
		// sysRightsService.getSysRoleByRightId(sysRights.getId().toString())
		// .getData();
		// String[] roleNames = new String[roles.size()];
		// for (int i = 0; i < roles.size(); i++) {
		// roleNames[i] = roles.get(i).getName();
		// }
		// switch (sysRights.getAuthType()) {
		// case SysRouteAuthoriseType.hasRole: // 一般不使用这个,需要在持久层加前缀ROLE_
		// http.authorizeRequests().antMatchers(sysRights.getUrl()).hasAnyRole(roleNames);
		// break;
		// case SysRouteAuthoriseType.hasAuthenticated:
		// http.authorizeRequests().antMatchers(sysRights.getUrl()).hasAnyAuthority(roleNames);
		// break;
		// case SysRouteAuthoriseType.authenticated:
		// http.authorizeRequests().antMatchers(sysRights.getUrl()).authenticated();
		// break;
		// case SysRouteAuthoriseType.permitAll:
		// http.authorizeRequests().antMatchers(sysRights.getUrl()).permitAll();
		// break;
		// case SysRouteAuthoriseType.denyAll:
		// http.authorizeRequests().antMatchers(sysRights.getUrl()).denyAll();
		// break;
		// case SysRouteAuthoriseType.hasIpAddress:
		// for (SysRole sysRole : roles) {
		// http.authorizeRequests().antMatchers(sysRights.getUrl()).hasIpAddress(sysRole.getName());
		// }
		// break;
		// }
		// }
		// }
		http.authorizeRequests().antMatchers("/public/**").permitAll().anyRequest().authenticated();
	}

	// @Bean
	// public TokenBasedAuthenticationFilter tokenBasedAuthenticationFilter() {
	// return new TokenBasedAuthenticationFilter("/api/**",
	// authTokenGeneratorService, authTokenService);
	// }
	// 认证 鉴定-Authentication
	@Bean
	public AuthenticationProvider authenticationProvider() {
		AuthenticationProvider authenticationPorvider = new AuthenticationProviderCustom(customUserService());
		return authenticationPorvider;
	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.authenticationProvider(authenticationProvider());
	}

	@Bean
	public AuthenticationSuccessHandler authenticationSuccessHandler() {
		return new AuthenticationSuccessHandlerImpl();
	}

	@Bean
	public AuthenticationFailureHandler authenticationFailureHandler() {
		return new AuthenticationFailureHandlerImpl();
	}

	@Bean
	public LogoutSuccessHandler logoutSuccessHandler() {
		return new LogoutSuccessHandlerImpl();
	}

}